package com.wonders.hisdoctor.station.project.laboratory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wonders.his.common.exception.CustomException;
import com.wonders.his.common.service.utils.CountAgeUtil;
import com.wonders.his.common.utils.DateUtils;
import com.wonders.his.common.utils.StringUtils;
import com.wonders.his.framework.utils.oracle.IdUtils;
import com.wonders.hisdoctor.station.constant.Constants;
import com.wonders.hisdoctor.station.constant.ServiceConstant;
import com.wonders.hisdoctor.station.enums.ChargeIndicatorEnum;
import com.wonders.hisdoctor.station.enums.ItemClassEnum;
import com.wonders.hisdoctor.station.enums.OracleSequenceEnum;
import com.wonders.hisdoctor.station.enums.ResultStatusEnum;
import com.wonders.hisdoctor.station.project.base.domain.*;
import com.wonders.hisdoctor.station.project.base.mapper.*;
import com.wonders.hisdoctor.station.project.laboratory.mapper.LaboratoryMapper;
import com.wonders.hisdoctor.station.project.laboratory.service.ILaboratoryService;
import com.wonders.hisdoctor.station.project.laboratory.vo.*;
import com.wonders.hisdoctor.station.util.CommonUtil;
import com.wonders.hisdoctor.station.util.PrecsIdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhaogongming
 * @date 2021-02-04
 **/
@Service
public class LaboratoryServiceImpl implements ILaboratoryService {

    @Autowired
    private LaboratoryMapper laboratoryMapper;

    @Autowired
    private OutpOrdersMapper outpOrdersMapper;

    @Autowired
    private OutpOrdersTMapper outpOrdersTMapper;

    @Autowired
    private OutpTreatRecMapper outpTreatRecMapper;

    @Autowired
    private OutpTreatRecTMapper outpTreatRecTMapper;

    @Autowired
    private IdUtils idUtils;

    @Autowired
    private LabTestMasterMapper labTestMasterMapper;

    @Autowired
    private LabTestItemsMapper labTestItemsMapper;

    @Autowired
    private PrecsIdGenerator precsIdGenerator;

    @Autowired
    private CommonUtil commonUtil;

    @Override
    public List<DeptResponseVo> selectDeptList(String hospitalCode) {
        return laboratoryMapper.selectDeptList(hospitalCode);
    }

    @Override
    public List<LaboratoryResponseVo> selectLaboratoryList(LaboratoryRequestVo laboratoryRequestVo) {
        return laboratoryMapper.selectLaboratoryList(laboratoryRequestVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(LaboratorySaveRequestVo laboratorySaveVo) {
        if (CollectionUtils.isEmpty(laboratorySaveVo.getOutpTreatRecList())) {
            throw new CustomException("请选择检验申请单");
        }
        //add 门诊医嘱处方主记录表
        String serialNo = idUtils.getNextVal(OracleSequenceEnum.SEQ_OUTP_ORDERS.getCode()).toString();
        OutpOrders outpOrders = laboratorySaveVo.getOutpOrders();
        outpOrders.setSerialNo(serialNo);
        //todo 取数据库时间
        outpOrders.setOrderDate(new Date());
        this.outpOrdersMapper.insert(outpOrders);

        //add 门诊医嘱处方主记录临时表
        OutpOrdersT outpOrdersT = new OutpOrdersT();
        BeanUtils.copyProperties(outpOrders, outpOrdersT);
        this.outpOrdersTMapper.insert(outpOrdersT);

        //add 检查治疗医嘱明细记录表
        List<OutpTreatRec> outpTreatRecList = new ArrayList<>();
        //add 检查治疗医嘱明细记录临时表
        List<OutpTreatRecT> outpTreatRecTList = new ArrayList<>();
        //add 检验项目表
        List<LabTestItems> labTestItemsList = new ArrayList<>();
        List<LaboratorySaveExpend> list = laboratorySaveVo.getOutpTreatRecList();
        for (int i = 0; i < list.size(); i++) {
            LaboratorySaveExpend lse = list.get(i);
            OutpTreatRec otr = new OutpTreatRec();
            BeanUtils.copyProperties(lse, otr);
            //申请单号
            String testNo = precsIdGenerator.getPrescId();

            //检验主记录表
            LabTestMaster labTestMaster = new LabTestMaster();
            BeanUtils.copyProperties(laboratorySaveVo.getLabTestMaster(), labTestMaster);
            labTestMaster.setSpecimen(lse.getSpecimen());
            labTestMaster.setNotesForSpcm(lse.getNotesForSpcm());
            labTestMaster.setTestNo(testNo);
            labTestMaster.setResultStatus(ResultStatusEnum.APPLICATION_RECEIPT.getCode());
            labTestMaster.setRequestedDateTime(new Date());
            labTestMaster.setPerformedBy(lse.getPerformedBy());
            labTestMaster.setCosts(lse.getCosts());
            this.labTestMasterMapper.insert(labTestMaster);

            //检验项目表
            LabTestItems labTestItems = new LabTestItems();
            labTestItems.setTestNo(testNo);
            labTestItems.setItemNo(Constants.ITEM_NO);
            labTestItems.setItemName(otr.getItemName());
            labTestItems.setItemCode(otr.getItemCode());
            labTestItemsList.add(labTestItems);

            //检查治疗医嘱明细记录表
            OutpTreatRec outpTreatRec = new OutpTreatRec();
            BeanUtils.copyProperties(otr, outpTreatRec);
            outpTreatRec.setSerialNo(serialNo);
            outpTreatRec.setItemClass(ItemClassEnum.TEST.getCode());
            outpTreatRec.setChargeIndicator(ChargeIndicatorEnum.ORDERED.getCode());
            outpTreatRec.setItemNo(i + 1);
            outpTreatRec.setAppointNo(testNo);
            outpTreatRec.setAppointItemNo(Constants.ITEM_NO);
            outpTreatRecList.add(outpTreatRec);

            //检查治疗医嘱明细记录临时表
            OutpTreatRecT outpTreatRecT = new OutpTreatRecT();
            BeanUtils.copyProperties(outpTreatRec, outpTreatRecT);
            outpTreatRecTList.add(outpTreatRecT);
        }
        this.outpTreatRecMapper.insertBatch(outpTreatRecList);
        this.outpTreatRecTMapper.insertBatch(outpTreatRecTList);
        this.labTestItemsMapper.insertBatch(labTestItemsList);
        return 1;
    }

    /**
     * 新版：加组合名称
     *
     * @param laboratorySaveVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveNew(LaboratorySaveRequestVo laboratorySaveVo) {
        if (CollectionUtils.isEmpty(laboratorySaveVo.getOutpTreatRecList())) {
            throw new CustomException("请选择检验申请单");
        }
        //流水号
        String serialNo = idUtils.getNextVal(OracleSequenceEnum.SEQ_OUTP_ORDERS.getCode()).toString();
        //1. add 门诊医嘱处方主记录表
        OutpOrders outpOrders = laboratorySaveVo.getOutpOrders();
        outpOrders.setSerialNo(serialNo);
        outpOrders.setOrderDate(new Date());
        this.outpOrdersMapper.insert(outpOrders);

        //2. add 门诊医嘱处方主记录临时表
        OutpOrdersT outpOrdersT = new OutpOrdersT();
        BeanUtils.copyProperties(outpOrders, outpOrdersT);
        this.outpOrdersTMapper.insert(outpOrdersT);

        //3. add 检查治疗医嘱明细记录表
        List<OutpTreatRec> outpTreatRecList = new ArrayList<>();
        //4. add 检查治疗医嘱明细记录临时表
        List<OutpTreatRecT> outpTreatRecTList = new ArrayList<>();
        //5. add 检验项目表
        List<LabTestItems> labTestItemsList = new ArrayList<>();

        List<LaboratorySaveExpend> list = laboratorySaveVo.getOutpTreatRecList();
        // 项目序号
        AtomicInteger treatIndex = new AtomicInteger(0);
        list.stream().collect(Collectors.groupingBy(LaboratorySaveExpend::getLabSheetId, LinkedHashMap::new, Collectors.toList())).forEach((labSheetId, groupList) -> {
            if (groupList.size() > 1) {
                //组合，多于1行。1.1.23 检验主记录EXAM.LAB_TEST_MASTER只存一行

                LaboratorySaveExpend lse = new LaboratorySaveExpend();
                //检验申请单号
                String testNo = precsIdGenerator.getPrescId();

                for (int i = 0; i < groupList.size(); i++) {
                    //
                    lse = groupList.get(i);
                    //5.1 检验项目表
                    LabTestItems labTestItems = new LabTestItems();
                    labTestItems.setTestNo(testNo);
                    labTestItems.setItemNo(i + 1);
                    labTestItems.setItemName(lse.getItemName());
                    labTestItems.setItemCode(lse.getItemCode());
                    labTestItems.setLabSheetId(lse.getLabSheetId());
                    labTestItems.setSheetTitle(lse.getSheetTitle());
                    labTestItemsList.add(labTestItems);

                    //3.1 检查治疗医嘱明细记录表
                    OutpTreatRec outpTreatRec = new OutpTreatRec();
                    BeanUtils.copyProperties(lse, outpTreatRec);
                    outpTreatRec.setSerialNo(serialNo);
                    outpTreatRec.setItemClass(ItemClassEnum.TEST.getCode());
                    outpTreatRec.setChargeIndicator(ChargeIndicatorEnum.ORDERED.getCode());
                    outpTreatRec.setItemNo(treatIndex.incrementAndGet());
                    outpTreatRec.setAppointNo(testNo);
                    outpTreatRec.setAppointItemNo(i + 1);
                    outpTreatRec.setCombCode(lse.getLabSheetId());
                    outpTreatRec.setCombName(lse.getSheetTitle());
                    outpTreatRecList.add(outpTreatRec);

                    //4.1 检查治疗医嘱明细记录临时表
                    OutpTreatRecT outpTreatRecT = new OutpTreatRecT();
                    BeanUtils.copyProperties(outpTreatRec, outpTreatRecT);
                    outpTreatRecTList.add(outpTreatRecT);
                }
                //6. 检验主记录表
                LabTestMaster labTestMaster = new LabTestMaster();
                BeanUtils.copyProperties(laboratorySaveVo.getLabTestMaster(), labTestMaster);
                labTestMaster.setSpecimen(lse.getSpecimen());
                labTestMaster.setNotesForSpcm(lse.getNotesForSpcm());
                labTestMaster.setTestNo(testNo);
                labTestMaster.setResultStatus(ResultStatusEnum.APPLICATION_RECEIPT.getCode());
                labTestMaster.setRequestedDateTime(new Date());
                labTestMaster.setPerformedBy(lse.getPerformedBy());
                if (StringUtils.isEmpty(lse.getSerialNo())) {
                    labTestMaster.setCosts(groupList.stream().map(LaboratorySaveExpend::getCosts).reduce(BigDecimal::add).get());
                }
                this.labTestMasterMapper.insert(labTestMaster);
            } else {
                for (int i = 0; i < groupList.size(); i++) {
                    //
                    LaboratorySaveExpend lse = groupList.get(i);

                    //检验申请单号
                    String testNo = precsIdGenerator.getPrescId();

                    //6. 检验主记录表
                    LabTestMaster labTestMaster = new LabTestMaster();
                    BeanUtils.copyProperties(laboratorySaveVo.getLabTestMaster(), labTestMaster);
                    labTestMaster.setSpecimen(lse.getSpecimen());
                    labTestMaster.setNotesForSpcm(lse.getNotesForSpcm());
                    labTestMaster.setTestNo(testNo);
                    labTestMaster.setResultStatus(ResultStatusEnum.APPLICATION_RECEIPT.getCode());
                    labTestMaster.setRequestedDateTime(new Date());
                    labTestMaster.setPerformedBy(lse.getPerformedBy());
                    labTestMaster.setCosts(lse.getCosts());
                    this.labTestMasterMapper.insert(labTestMaster);

                    //5.1 检验项目表
                    LabTestItems labTestItems = new LabTestItems();
                    labTestItems.setTestNo(testNo);
                    labTestItems.setItemNo(Constants.ITEM_NO);
                    labTestItems.setItemName(lse.getItemName());
                    labTestItems.setItemCode(lse.getItemCode());
                    labTestItems.setLabSheetId(lse.getLabSheetId());
                    labTestItems.setSheetTitle(lse.getSheetTitle());
                    labTestItemsList.add(labTestItems);

                    //3.1 检查治疗医嘱明细记录表
                    OutpTreatRec outpTreatRec = new OutpTreatRec();
                    BeanUtils.copyProperties(lse, outpTreatRec);
                    outpTreatRec.setSerialNo(serialNo);
                    outpTreatRec.setItemClass(ItemClassEnum.TEST.getCode());
                    outpTreatRec.setChargeIndicator(ChargeIndicatorEnum.ORDERED.getCode());
                    outpTreatRec.setItemNo(treatIndex.incrementAndGet());
                    outpTreatRec.setAppointNo(testNo);
                    outpTreatRec.setAppointItemNo(Constants.ITEM_NO);
                    outpTreatRec.setCombCode(lse.getLabSheetId());
                    outpTreatRec.setCombName(lse.getSheetTitle());
                    outpTreatRecList.add(outpTreatRec);

                    //4.1 检查治疗医嘱明细记录临时表
                    OutpTreatRecT outpTreatRecT = new OutpTreatRecT();
                    BeanUtils.copyProperties(outpTreatRec, outpTreatRecT);
                    outpTreatRecTList.add(outpTreatRecT);
                }
            }
        });
        this.outpTreatRecMapper.insertBatch(outpTreatRecList);
        this.outpTreatRecTMapper.insertBatch(outpTreatRecTList);
        this.labTestItemsMapper.insertBatch(labTestItemsList);
        return 1;
    }

    @Override
    public List<LaboratoryResponseVo> selectLaboratory(LaboratoryInfoRequestVo laboratoryInfoRequestVo) {
        return laboratoryMapper.selectLaboratory(laboratoryInfoRequestVo);
    }

    /**
     * 新版：加组合名称
     *
     * @param laboratoryInfoRequestVo
     * @return
     */
    @Override
    public List<LaboratoryResponseVo> selectLaboratoryNew(LaboratoryInfoRequestVo laboratoryInfoRequestVo) {
        return laboratoryMapper.selectLaboratoryNew(laboratoryInfoRequestVo);
    }

    @Override
    public List<LaboratoryResponseVo> selectHistoryLaboratory(LaboratoryHistoryRequestVo laboratoryHistoryRequestVo) {
        return laboratoryMapper.selectHistoryLaboratory(laboratoryHistoryRequestVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer cancelLaboratory(List<CancelLaboratoryRequestVo> list) {
        if (CollectionUtils.isEmpty(list)) {
            throw new CustomException("请选择检验申请单！");
        }
        for (CancelLaboratoryRequestVo entity : list) {
            QueryWrapper<OutpTreatRec> otrQueryWrapper = new QueryWrapper<>();
            otrQueryWrapper.eq(ServiceConstant.SERIAL_NO, entity.getSerialNo()).eq(ServiceConstant.ITEM_NO, entity.getItemNo()).in(ServiceConstant.CHARGE_INDICATOR, ChargeIndicatorEnum.PAID.getCode(), ChargeIndicatorEnum.RETURN_PAID.getCode());
            OutpTreatRec outpTreatRec = this.outpTreatRecMapper.selectOne(otrQueryWrapper);
            if (null != outpTreatRec) {
                throw new CustomException("无法删除已缴费/已退费的申请单！");
            }
        }
        //1. 删除 检查治疗表
        this.laboratoryMapper.deleteBatchOutpTreatRec(list);
        //2. 删除 检查治疗临时表
        this.laboratoryMapper.deleteBatchOutpTreatRecT(list);
        //3. 删除 检验主记录表
        this.laboratoryMapper.deleteBatchLabTestMaster(list);
        //4. 删除 检验项目表
        this.laboratoryMapper.deleteBatchLabTestItems(list);
        for (CancelLaboratoryRequestVo entity : list) {
            String serialNo = entity.getSerialNo();
            QueryWrapper<OutpTreatRec> queryOtrWrapper = new QueryWrapper<>();
            queryOtrWrapper.eq(ServiceConstant.SERIAL_NO, serialNo);
            Integer count = this.outpTreatRecMapper.selectCount(queryOtrWrapper);
            if (count == 0) {
                //5. 删除 处方主记录表
                this.outpOrdersMapper.deleteById(serialNo);
                //6. 删除 处方主记录临时表
                this.outpOrdersTMapper.deleteById(serialNo);
            }
        }
        return 1;
    }

    @Override
    public List<LaboratoryPrintReponseVo> selectPrintInfo(List<LaboratoryPrintRequestVo> list) {
        if (CollectionUtils.isEmpty(list)) {
            throw new CustomException("请选择检验申请单！");
        }
        List<LaboratoryPrintReponseVo> laboratoryPrintReponseVos = laboratoryMapper.selectPrintInfo(list);
        if (!CollectionUtils.isEmpty(laboratoryPrintReponseVos)) {
            //过去重复检验申请单
            laboratoryPrintReponseVos = laboratoryPrintReponseVos.stream().collect(Collectors.toMap(LaboratoryPrintReponseVo::getTestNo, Function.identity(), (oldValue, newValue) -> oldValue))
                    .values().stream().collect(Collectors.toList());
            //设置年龄为岁数
            Date dateOfBirth = laboratoryPrintReponseVos.get(0).getDateOfBirth();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.YYYY_MM_DD);
            String ageStr = CountAgeUtil.getAgeStr(simpleDateFormat.format(dateOfBirth));
            laboratoryPrintReponseVos.forEach(e -> {
                e.setAgeStr(ageStr);
                e.setTitle(commonUtil.setPrintTitle(e.getHospitalCode()));
            });
        }
        return laboratoryPrintReponseVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<LaboratoryPrintReponseVo> saveAndPrint(LaboratorySaveRequestVo laboratorySaveVo) {
        if (CollectionUtils.isEmpty(laboratorySaveVo.getOutpTreatRecList())) {
            throw new CustomException("请选择检验申请单");
        }
        //add 门诊医嘱处方主记录表
        String serialNo = idUtils.getNextVal(OracleSequenceEnum.SEQ_OUTP_ORDERS.getCode()).toString();

        //判断：如果全是已开单，不插入
        if (laboratorySaveVo.getOutpTreatRecList().stream().anyMatch(p -> StringUtils.isEmpty(p.getSerialNo()))) {
            OutpOrders outpOrders = laboratorySaveVo.getOutpOrders();
            outpOrders.setSerialNo(serialNo);
            //todo 取数据库时间
            outpOrders.setOrderDate(new Date());
            this.outpOrdersMapper.insert(outpOrders);

            //add 门诊医嘱处方主记录临时表
            OutpOrdersT outpOrdersT = new OutpOrdersT();
            BeanUtils.copyProperties(outpOrders, outpOrdersT);
            this.outpOrdersTMapper.insert(outpOrdersT);
        }

        //add 检查治疗医嘱明细记录表
        List<OutpTreatRec> outpTreatRecList = new ArrayList<>();
        //add 检查治疗医嘱明细记录临时表
        List<OutpTreatRecT> outpTreatRecTList = new ArrayList<>();
        //打印申请传参
        List<LaboratoryPrintRequestVo> outpTreatRecPrintList = new ArrayList<>();
        //add 检验项目表
        List<LabTestItems> labTestItemsList = new ArrayList<>();
        List<LaboratorySaveExpend> list = laboratorySaveVo.getOutpTreatRecList();
        for (int i = 0; i < list.size(); i++) {
            LaboratorySaveExpend lse = list.get(i);
            if (!StringUtils.isEmpty(lse.getSerialNo())) {
                LaboratoryPrintRequestVo laboratoryPrintRequestVo = new LaboratoryPrintRequestVo();
                laboratoryPrintRequestVo.setTestNo(lse.getAppointNo());
                outpTreatRecPrintList.add(laboratoryPrintRequestVo);
                continue;
            }
            OutpTreatRec otr = new OutpTreatRec();
            BeanUtils.copyProperties(lse, otr);
            //申请单号
            String testNo = precsIdGenerator.getPrescId();

            //检验主记录表
            LabTestMaster labTestMaster = new LabTestMaster();
            BeanUtils.copyProperties(laboratorySaveVo.getLabTestMaster(), labTestMaster);
            labTestMaster.setSpecimen(lse.getSpecimen());
            labTestMaster.setNotesForSpcm(lse.getNotesForSpcm());
            labTestMaster.setTestNo(testNo);
            labTestMaster.setResultStatus(ResultStatusEnum.APPLICATION_RECEIPT.getCode());
            labTestMaster.setRequestedDateTime(new Date());
            labTestMaster.setPerformedBy(lse.getPerformedBy());
            labTestMaster.setCosts(lse.getCosts());
            this.labTestMasterMapper.insert(labTestMaster);

            //检验项目表
            LabTestItems labTestItems = new LabTestItems();
            labTestItems.setTestNo(testNo);
            labTestItems.setItemNo(Constants.ITEM_NO);
            labTestItems.setItemName(otr.getItemName());
            labTestItems.setItemCode(otr.getItemCode());
            labTestItemsList.add(labTestItems);

            //检查治疗医嘱明细记录表
            OutpTreatRec outpTreatRec = new OutpTreatRec();
            BeanUtils.copyProperties(otr, outpTreatRec);
            outpTreatRec.setSerialNo(serialNo);
            outpTreatRec.setItemClass(ItemClassEnum.TEST.getCode());
            outpTreatRec.setChargeIndicator(ChargeIndicatorEnum.ORDERED.getCode());
            outpTreatRec.setItemNo(i + 1);
            outpTreatRec.setAppointNo(testNo);
            outpTreatRec.setAppointItemNo(Constants.ITEM_NO);
            outpTreatRecList.add(outpTreatRec);

            //打印申请参数
            LaboratoryPrintRequestVo laboratoryPrintRequestVo = new LaboratoryPrintRequestVo();
            laboratoryPrintRequestVo.setTestNo(testNo);
            outpTreatRecPrintList.add(laboratoryPrintRequestVo);

            //检查治疗医嘱明细记录临时表
            OutpTreatRecT outpTreatRecT = new OutpTreatRecT();
            BeanUtils.copyProperties(outpTreatRec, outpTreatRecT);
            outpTreatRecTList.add(outpTreatRecT);
        }
        if (!CollectionUtils.isEmpty(outpTreatRecList)) {
            this.outpTreatRecMapper.insertBatch(outpTreatRecList);
            this.outpTreatRecTMapper.insertBatch(outpTreatRecTList);
            this.labTestItemsMapper.insertBatch(labTestItemsList);
        }
        return this.selectPrintInfo(outpTreatRecPrintList);
    }

    /**
     * 新版：加组合名称
     *
     * @param laboratorySaveVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<LaboratoryPrintReponseVo> saveAndPrintNew(LaboratorySaveRequestVo laboratorySaveVo) {

        if (CollectionUtils.isEmpty(laboratorySaveVo.getOutpTreatRecList())) {
            throw new CustomException("请选择检验申请单");
        }
        //1. add 门诊医嘱处方主记录表
        String serialNo = idUtils.getNextVal(OracleSequenceEnum.SEQ_OUTP_ORDERS.getCode()).toString();

        //判断：如果全是已开单，不插入
        if (laboratorySaveVo.getOutpTreatRecList().stream().anyMatch(p -> StringUtils.isEmpty(p.getSerialNo()))) {
            OutpOrders outpOrders = laboratorySaveVo.getOutpOrders();
            outpOrders.setSerialNo(serialNo);
            outpOrders.setOrderDate(new Date());
            this.outpOrdersMapper.insert(outpOrders);

            //2. add 门诊医嘱处方主记录临时表
            OutpOrdersT outpOrdersT = new OutpOrdersT();
            BeanUtils.copyProperties(outpOrders, outpOrdersT);
            this.outpOrdersTMapper.insert(outpOrdersT);
        }

        //3. add 检查治疗医嘱明细记录表
        List<OutpTreatRec> outpTreatRecList = new ArrayList<>();
        //4. add 检查治疗医嘱明细记录临时表
        List<OutpTreatRecT> outpTreatRecTList = new ArrayList<>();
        //5. add 检验项目表
        List<LabTestItems> labTestItemsList = new ArrayList<>();
        //打印申请传参
        List<LaboratoryPrintRequestVo> outpTreatRecPrintList = new ArrayList<>();

        List<LaboratorySaveExpend> list = laboratorySaveVo.getOutpTreatRecList();
        // 项目序号
        AtomicInteger treatIndex = new AtomicInteger(0);
        list.stream().collect(Collectors.groupingBy(LaboratorySaveExpend::getLabSheetId, LinkedHashMap::new, Collectors.toList())).forEach((labSheetId, groupList) -> {
            if (groupList.size() > 1) {
                //组合，多于1行。1.1.23 检验主记录EXAM.LAB_TEST_MASTER只存一行
                LaboratorySaveExpend lse = new LaboratorySaveExpend();
                //检验申请单号
                String testNo = precsIdGenerator.getPrescId();

                for (int i = 0; i < groupList.size(); i++) {
                    //
                    lse = groupList.get(i);

                    //已开单，只需要获取打印信息
                    if (!StringUtils.isEmpty(lse.getSerialNo())) {
                        LaboratoryPrintRequestVo laboratoryPrintRequestVo = new LaboratoryPrintRequestVo();
                        laboratoryPrintRequestVo.setTestNo(lse.getAppointNo());
                        outpTreatRecPrintList.add(laboratoryPrintRequestVo);
                        continue;
                    }

                    //5.1 检验项目表
                    LabTestItems labTestItems = new LabTestItems();
                    labTestItems.setTestNo(testNo);
                    labTestItems.setItemNo(i + 1);
                    labTestItems.setItemName(lse.getItemName());
                    labTestItems.setItemCode(lse.getItemCode());
                    labTestItems.setLabSheetId(lse.getLabSheetId());
                    labTestItems.setSheetTitle(lse.getSheetTitle());
                    labTestItemsList.add(labTestItems);

                    //3.1 检查治疗医嘱明细记录表
                    OutpTreatRec outpTreatRec = new OutpTreatRec();
                    BeanUtils.copyProperties(lse, outpTreatRec);
                    outpTreatRec.setSerialNo(serialNo);
                    outpTreatRec.setItemClass(ItemClassEnum.TEST.getCode());
                    outpTreatRec.setChargeIndicator(ChargeIndicatorEnum.ORDERED.getCode());
                    outpTreatRec.setItemNo(treatIndex.incrementAndGet());
                    outpTreatRec.setAppointNo(testNo);
                    outpTreatRec.setAppointItemNo(i + 1);
                    outpTreatRec.setCombCode(lse.getLabSheetId());
                    outpTreatRec.setCombName(lse.getSheetTitle());
                    outpTreatRecList.add(outpTreatRec);

                    //打印申请参数
                    LaboratoryPrintRequestVo laboratoryPrintRequestVo = new LaboratoryPrintRequestVo();
                    laboratoryPrintRequestVo.setTestNo(testNo);
                    outpTreatRecPrintList.add(laboratoryPrintRequestVo);

                    //4.1 检查治疗医嘱明细记录临时表
                    OutpTreatRecT outpTreatRecT = new OutpTreatRecT();
                    BeanUtils.copyProperties(outpTreatRec, outpTreatRecT);
                    outpTreatRecTList.add(outpTreatRecT);
                }
                //6. 检验主记录表
                if (StringUtils.isEmpty(lse.getSerialNo())) {
                    LabTestMaster labTestMaster = new LabTestMaster();
                    BeanUtils.copyProperties(laboratorySaveVo.getLabTestMaster(), labTestMaster);
                    labTestMaster.setSpecimen(lse.getSpecimen());
                    labTestMaster.setNotesForSpcm(lse.getNotesForSpcm());
                    labTestMaster.setTestNo(testNo);
                    labTestMaster.setResultStatus(ResultStatusEnum.APPLICATION_RECEIPT.getCode());
                    labTestMaster.setRequestedDateTime(new Date());
                    labTestMaster.setPerformedBy(lse.getPerformedBy());
                    labTestMaster.setCosts(groupList.stream().map(LaboratorySaveExpend::getCosts).reduce(BigDecimal::add).get());
                    this.labTestMasterMapper.insert(labTestMaster);
                }
            } else {
                for (int i = 0; i < groupList.size(); i++) {
                    //
                    LaboratorySaveExpend lse = groupList.get(i);

                    //已开单，只需要获取打印信息
                    if (!StringUtils.isEmpty(lse.getSerialNo())) {
                        LaboratoryPrintRequestVo laboratoryPrintRequestVo = new LaboratoryPrintRequestVo();
                        laboratoryPrintRequestVo.setTestNo(lse.getAppointNo());
                        outpTreatRecPrintList.add(laboratoryPrintRequestVo);
                        continue;
                    }

                    //检验申请单号
                    String testNo = precsIdGenerator.getPrescId();

                    //6. 检验主记录表
                    LabTestMaster labTestMaster = new LabTestMaster();
                    BeanUtils.copyProperties(laboratorySaveVo.getLabTestMaster(), labTestMaster);
                    labTestMaster.setSpecimen(lse.getSpecimen());
                    labTestMaster.setNotesForSpcm(lse.getNotesForSpcm());
                    labTestMaster.setTestNo(testNo);
                    labTestMaster.setResultStatus(ResultStatusEnum.APPLICATION_RECEIPT.getCode());
                    labTestMaster.setRequestedDateTime(new Date());
                    labTestMaster.setPerformedBy(lse.getPerformedBy());
                    labTestMaster.setCosts(lse.getCosts());
                    this.labTestMasterMapper.insert(labTestMaster);

                    //5.1 检验项目表
                    LabTestItems labTestItems = new LabTestItems();
                    labTestItems.setTestNo(testNo);
                    labTestItems.setItemNo(Constants.ITEM_NO);
                    labTestItems.setItemName(lse.getItemName());
                    labTestItems.setItemCode(lse.getItemCode());
                    labTestItems.setLabSheetId(lse.getLabSheetId());
                    labTestItems.setSheetTitle(lse.getSheetTitle());
                    labTestItemsList.add(labTestItems);

                    //3.1 检查治疗医嘱明细记录表
                    OutpTreatRec outpTreatRec = new OutpTreatRec();
                    BeanUtils.copyProperties(lse, outpTreatRec);
                    outpTreatRec.setSerialNo(serialNo);
                    outpTreatRec.setItemClass(ItemClassEnum.TEST.getCode());
                    outpTreatRec.setChargeIndicator(ChargeIndicatorEnum.ORDERED.getCode());
                    outpTreatRec.setItemNo(treatIndex.incrementAndGet());
                    outpTreatRec.setAppointNo(testNo);
                    outpTreatRec.setAppointItemNo(Constants.ITEM_NO);
                    outpTreatRec.setCombCode(lse.getLabSheetId());
                    outpTreatRec.setCombName(lse.getSheetTitle());
                    outpTreatRecList.add(outpTreatRec);

                    //打印申请参数
                    LaboratoryPrintRequestVo laboratoryPrintRequestVo = new LaboratoryPrintRequestVo();
                    laboratoryPrintRequestVo.setTestNo(testNo);
                    outpTreatRecPrintList.add(laboratoryPrintRequestVo);

                    //4.1 检查治疗医嘱明细记录临时表
                    OutpTreatRecT outpTreatRecT = new OutpTreatRecT();
                    BeanUtils.copyProperties(outpTreatRec, outpTreatRecT);
                    outpTreatRecTList.add(outpTreatRecT);
                }
            }
        });
        if (!CollectionUtils.isEmpty(outpTreatRecList)) {
            this.outpTreatRecMapper.insertBatch(outpTreatRecList);
            this.outpTreatRecTMapper.insertBatch(outpTreatRecTList);
            this.labTestItemsMapper.insertBatch(labTestItemsList);
        }
        return this.selectPrintInfo(outpTreatRecPrintList);
    }
}
